#include "modules/record_mgr.h"
#include "types/errors.h"

void create_table_test(char **argv)
{
	string table_name(argv[2]);
	int num_attrs;
	
	sscanf(argv[3], "%d", &num_attrs);
	
	printf("\nCreating table %s with %d attributes", table_name.c_str(), num_attrs);
	
	BufferManager::initialize(3);
	RecordManager r;
	
	r.create_table(table_name, num_attrs);
	BufferManager::deinitialize();
}

void add_record_test(char **argv)
{
	string table_name(argv[2]);
	BufferManager::initialize(3);
	RecordManager r;
	
	int num_attrs;
	sscanf(argv[3], "%d", &num_attrs);
	
	
	int v;
	vector<UINT32> values;
	
	for(int i=4; i< num_attrs + 4; i++)
	{
		sscanf(argv[i], "%d", &v);
		values.push_back(v);
	}
	Record rec(values);
	r.add_record(table_name, rec);
	BufferManager::deinitialize();
}


void read_all_test(char **argv)
{
	string table_name(argv[2]);
	BufferManager::initialize(3);
	RecordManager r;
	
	int num_attrs;
	sscanf(argv[3], "%d", &num_attrs);

	vector<Record> result = r.read_records(table_name);
	for(int i=0; i<result.size(); i++)
	{
		for(int j=0; j<num_attrs;j++)
		{
			printf("%d ",result[i].attribute(j));
		}
		printf("\n");
	}
	BufferManager::deinitialize();
}

void read_cond_test(char **argv)
{
	string table_name(argv[2]);
	BufferManager::initialize(3);
	RecordManager r;
	
	int num_attrs, lvalue, rvalue;
	sscanf(argv[3], "%d", &num_attrs);
	
	string type(argv[4]);
	enum ConditionType t = (type == "attr_check") ? attr_check : val_check;

	sscanf(argv[5], "%d", &lvalue);
	sscanf(argv[6], "%d", &rvalue);

	Condition c = {t, eq, lvalue, rvalue};
	vector<Record> result = r.read_records(table_name, c);
	for(int i=0; i<result.size(); i++)
	{
		for(int j=0; j<num_attrs;j++)
		{
			printf("%d ",result[i].attribute(j));
		}
		printf("\n");
	}
	BufferManager::deinitialize();
}

void read_AND_test(char **argv)
{
	string table_name(argv[2]);
	BufferManager::initialize(3);
	RecordManager r;
	
	int num_attrs, lvalue, rvalue;
	sscanf(argv[3], "%d", &num_attrs);
	
	string type(argv[4]);
	enum ConditionType t = (type == "attr_check") ? attr_check : val_check;

	sscanf(argv[5], "%d", &lvalue);
	sscanf(argv[6], "%d", &rvalue);

	Condition c = {t, eq, lvalue, rvalue};
	vector<Record> result1 = r.read_records(table_name, c);

	int lvalue2, rvalue2;
	string type2(argv[7]);
	enum ConditionType t2 = (type2 == "attr_check") ? attr_check : val_check;

	sscanf(argv[8], "%d", &lvalue2);
	sscanf(argv[9], "%d", &rvalue2);

	Condition c2 = {t2, eq, lvalue2, rvalue2};
	vector<Record> result2 = r.read_records(table_name, c2);

	vector<Record> result = r.common_records(result1,result2);
	for(int i=0; i<result.size(); i++)
	{
		for(int j=0; j<num_attrs;j++)
		{
			printf("%d ",result[i].attribute(j));
		}
		printf("\n");
	}
	BufferManager::deinitialize();
}


void read_OR_test(char **argv)
{
	string table_name(argv[2]);
	BufferManager::initialize(3);
	RecordManager r;
	
	int num_attrs, lvalue, rvalue;
	sscanf(argv[3], "%d", &num_attrs);
	
	string type(argv[4]);
	enum ConditionType t = (type == "attr_check") ? attr_check : val_check;

	sscanf(argv[5], "%d", &lvalue);
	sscanf(argv[6], "%d", &rvalue);

	Condition c = {t, eq, lvalue, rvalue};
	vector<Record> result1 = r.read_records(table_name, c);

	int lvalue2, rvalue2;
	string type2(argv[7]);
	enum ConditionType t2 = (type2 == "attr_check") ? attr_check : val_check;

	sscanf(argv[8], "%d", &lvalue2);
	sscanf(argv[9], "%d", &rvalue2);

	Condition c2 = {t2, eq, lvalue2, rvalue2};
	vector<Record> result2 = r.read_records(table_name, c2);

	vector<Record> result = r.merge_records(result1,result2);
	printf("\nreturned");
	fflush(stdout);
	for(int i=0; i<result.size(); i++)
	{
		for(int j=0; j<num_attrs;j++)
		{
			printf("%d ",result[i].attribute(j));
		}
		printf("\n");
	}
	BufferManager::deinitialize();
}

int main(int argc, char **argv)
{
	try
	{	
		if(argc < 2)
		{
			printf("recmgr_test [test_name] [test_params]");
			return -1;
		}
		
		string test_name(argv[1]);

		if(test_name == "create" && argc == 4)
		{
			create_table_test(argv);
		}
		else if(test_name == "insert" && argc >= 5)
		{
			add_record_test(argv);
		}
		else if(test_name == "readall"  && argc == 4)
		{
			read_all_test(argv);
		}
		else if(test_name == "condition"  && argc == 7)
		{
			read_cond_test(argv);
		}
		else if(test_name == "andtest"  && argc == 10)
		{
			read_AND_test(argv);
		}
		else if(test_name == "ortest"  && argc == 10)
		{
			read_OR_test(argv);
		}
	}
	catch(Exception e)
	{
		printf("\nCaught error : %d",e.errno);
	}
	
	return 0;
}
